﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WebGetter;
using Web.HttpUtility;
using System.IO;
using System.Drawing;
using System.Web;
using System.Net;
using System.Runtime.InteropServices;

namespace T114Getter
{
    class T114Getter
    {
        private string queryDataFormat = "%BB%FA%B9%B9%C3%FB%B3%C6_p=*&%BB%FA%B9%B9%C3%FB%B3%C6=&%B7%A8%C8%CB%B4%FA%B1%ED_p=*&%B7%A8%C8%CB%B4%FA%B1%ED=&%BB%FA%B9%B9%B5%D8%D6%B7_p=*&%BB%FA%B9%B9%B5%D8%D6%B7=&%BB%FA%B9%B9%B4%FA%C2%EB_p=*&%BB%FA%B9%B9%B4%FA%C2%EB=&%D7%A2%B2%E1%D7%CA%BD%F0_p={0}&%D7%A2%B2%E1%D7%CA%BD%F0={1}&%C5%FA%D7%BC%B3%C9%C1%A2%BB%FA%B9%B9_p=*&%C5%FA%D7%BC%B3%C9%C1%A2%BB%FA%B9%B9=&%B5%E7%BB%B0%BA%C5%C2%EB_p=*&%B5%E7%BB%B0%BA%C5%C2%EB=&%BB%FA%B9%B9%C0%E0%D0%CD_p=*&%BB%FA%B9%B9%C0%E0%D0%CD=&%B3%C9%C1%A2%C8%D5%C6%DA_p={2}&%B3%C9%C1%A2%C8%D5%C6%DA=&%BE%AD%D3%AA%B7%B6%CE%A7=";

        private CookieContainer cookies = new CookieContainer();
        StreamWriter w = null;
        Logger logger = new Logger();
        public void DoWork()
        {
            string dataFilePath = @"C:\114Data.csv";
            string loggerFilePath = @"C:\log.log";

            var loggerStream = File.AppendText(loggerFilePath);
            logger.RegistWriter(Console.Out);
            logger.RegistWriter(loggerStream);
            try
            {
                w = File.AppendText(dataFilePath);
                //请求验证码
                GetVerifyCode();
                //OpenExcel(excelFilePath);
                Console.WriteLine("Input verify code,press ENTER key");
                string verifyCode = Console.ReadLine();

                //STEP2 LOGIN
                if (!Login(verifyCode))
                {
                    logger.Log("Login Failure");
                    Done();
                    return;
                }

                SetPageSize();

                for (int i = 0; i < 365 * 6; i++)
                {
                    string date = new DateTime(2000, 1, 1).AddDays(+i).ToString("yyyy-MM-dd");
                    logger.Log(date);
                    GetData(date);
                }
            }
            finally
            {
                if (w != null)
                    w.Close();
            }

            //string nextUrl = helper.GetKeyItem("NextUrl");
            //File.WriteAllText(@"C:\1.txt", html);

            string logoutUrl = @"http://my.cdt114.com/hy/public/logout.asp";

            Done();
        }

        private static void Done()
        {
            Console.WriteLine("Press any key to quit");
            Console.ReadKey();
        }

        private string GetData(string date)
        {
            string amount = "50";
            string searchUrl = "http://my.cdt114.com/hy/Enterprise/index.asp?Act=SearchGo";
            string html = GetData(searchUrl, string.Format(queryDataFormat, HttpUtility.UrlEncode(">"), amount, date));
            html = GetData(searchUrl, string.Format(queryDataFormat, HttpUtility.UrlEncode("="), amount, date));
            html = GetData(searchUrl, string.Format(queryDataFormat, HttpUtility.UrlEncode("<"), amount, date));
            return html;
        }

        private string SetPageSize()
        {
            string url = "http://my.cdt114.com/hy/Enterprise/index.asp?Act1=&cachePage=200";
            string html = HttpHelper.GetHtml(url, cookies);
            return html;
        }

        private string GetData(string searchUrl, string queryData)
        {
            string html = HttpHelper.GetHtml(searchUrl, "POST", queryData, cookies);

            RegexHelper helper = ProcessContent(html);
            return html;
        }

        private bool Login(string verifyCode)
        {
            string postData = string.Format("username={0}&password={1}&userType=0&VerifyCode={2}&x=23&y=11", userName, passWord, verifyCode);
            string url = "http://my.cdt114.com/hy/public/chklogin.asp";
            string loginResult = HttpHelper.GetHtml(url, "POST", postData, cookies);
            return loginResult.Contains("Object moved");
        }

        private void GetVerifyCode()
        {
            HttpOptions option = new HttpOptions
            {
                Url = "http://my.cdt114.com/hy/Inc/vCode.asp?",
                Referer = "Referer: http://my.cdt114.com/hy/public/login.asp",
                CookieContainer = cookies
            };
            Stream stream = HttpHelper.GetStream(option);
            Image bitmap = Bitmap.FromStream(stream);
            bitmap.Save(@"C:\verifyCode.bmp");
        }

        private RegexHelper ProcessContent(string html)
        {
            if (html.Contains("暂无数据"))
            {
                //Console.WriteLine("没有找到数据");
                return null;
            }

            RegexHelper helper = new RegexHelper(html);

            helper.GetByRegexp("NextUrl", @"<a\shref=""(?<val>[^\""]+)""\sclass=""PageNext""\stitle=""下一页""></a>""");
            helper.GetByRegexp("Name", @"\<strong\>单位名称\</strong\>：(?<val>.+?)\<br\>");
            helper.GetByRegexp("Type", @"\<strong\>单位类型\</strong\>：(?<val>.+?)\<br\>");
            helper.GetByRegexp("Money", @"\<strong\>注册资金\</strong\>：(?<val>.+?)\<br\>");
            helper.GetByRegexp("BusinessScope", @"\<strong\>经营范围\</strong\>：(?<val>.+?)\<br\>");
            helper.GetByRegexp("RegisteAt", @"\<strong\>登记机关\</strong\>：(?<val>.+?)\</div\>");

            helper.GetAllByRegexp(@"\n\<td\salign=""left""\>(?<Address>.+?)\</td\>\s*\n\<td\salign=""left""\>(?<Owner>.+?)\</td\>\s*\n\<td\salign=""left""\>(?<Phone>.*?)\</td\>\s*\n\<td\salign=""left""\>(?<RegisteDate>.+?)\</td\>\s*\n\<tr");

            if (VerifyHelperData(helper))
                FillCompany(helper);
            else
                logger.Log("数据异常");
            return helper;
        }

        class Constant
        {
            public const string NextUrl = "NextUrl";
            public const string Name = "Name";
            public const string Type = "Type";
            public const string Money = "Money";
            public const string BusinessScope = "BusinessScope";
            public const string RegisteAt = "RegisteAt";
            public const string Address = "Address";
            public const string Owner = "Owner";
            public const string Phone = "Phone";
            public const string RegisteDate = "RegisteDate";
        }

        private bool VerifyHelperData(RegexHelper helper)
        {
            bool result = true;
            int count = helper[Constant.Name].Count;
            result = result && count == helper[Constant.Owner].Count;
            result = result && count == helper[Constant.Phone].Count;
            result = result && count == helper[Constant.Address].Count;
            result = result && count == helper[Constant.RegisteDate].Count;
            result = result && count == helper[Constant.Type].Count;
            if (result)
            {
                logger.Log(string.Format("\t\t{0}", count));
            }
            return result;
        }

        private void FillCompany(RegexHelper helper)
        {
            for (int i = 0; i < helper.DicData[Constant.Name].Count; i++)
            {
                Company company = new Company
                {
                    Name = helper.DicData[Constant.Name][i],
                    Owner = helper.DicData[Constant.Owner][i],
                    Address = helper.DicData[Constant.Address][i],
                    Phone = helper[Constant.Phone][i],
                    RegisteDate = helper[Constant.RegisteDate][i],
                    RegisteType = helper[Constant.Type][i]
                };
                //gettedCompanies.Add(company);
                SavePlantData(company);
                //SaveExcelData(company);
            }
        }

        private void SavePlantData(Company company)
        {
            w.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}", company.Name, company.Owner, company.Address, company.Phone, company.RegisteType, company.RegisteDate, DateTime.Now);
        }

        class Company
        {
            public string Name { get; set; }
            public string RegisteType { get; set; }
            public string RegisteMoney { get; set; }
            public string BusinessScope { get; set; }
            public string RigisteAt { get; set; }
            public string Address { get; set; }
            public string Owner { get; set; }
            public string Phone { get; set; }
            public string RegisteDate { get; set; }
        }

        private string userName = "*";
        private string passWord = "*";
        List<Company> gettedCompanies = new List<Company>();
    }
}
